Geospatial Data Visualization¶

Most famous GIS software like ArcGIS and QGIS provide an interface for coding with python.

Python is a great language for geographic data analysis.

  • Several libraries for GIS
  • Python GIS is efficent and flexible
  • It is free.
  • You are not limited with only one library/software

Core libraries for GIS in Python:

  • geopandas (vector data, uses points)
  • rasterio (raster data, pixels)
  • plotly can also be used for map visualization.

In this tutorial, we will work with vector data format(points, lines, areas)

The goal is not to overwhelm you with the underhood information, rather it is more pragmatic, I want to show how you can use Python for GIS work.

Knowing pandas is important because we are still working with pandas dataframe (with additional geometry or condinates columns).

Some key terms:

  • Coordinate reference system (CRS)
    • Map projections
    • European Petroleum Survey Group (EPSG) codes such as such as 4326 for WGS84
    • Well-known text (WKT)

Source

Source

Geopandas basics¶

Geopandas uses several other packages. One of them is shapely. It helps to create points, lines, poligons, etc.

Point()¶

In [1]:
from shapely.geometry import Point


point = Point(1.2, 3.1)
point3D = Point(9.26, -2.456, 0.57)

point
Out[1]:
In [2]:
print(point)
print(point3D)
POINT (1.2 3.1)
POINT Z (9.26 -2.456 0.57)
In [3]:
#coordinates of the point geometry
list(point.coords)
Out[3]:
[(1.2, 3.1)]
In [4]:
# coordinates
print(point.x)
print(point.y)
1.2
3.1

LineString¶

This is essentially means line.

We need least two points for creating a line.

In [5]:
from shapely.geometry import Point, LineString

point1 = Point(3.1, 4.9)
point2 = Point(6.7, -20.2)
point3 = Point(3.26, -19.456)

line = LineString([point1, point2, point3])
# line_from_tuples = LineString([(3.1, 4.9), (6.7, -20.2), (3.26, -6.456)])
line
Out[5]:
In [6]:
# this is actually WKT representation of the line

print(line)
LINESTRING (3.1 4.9, 6.7 -20.2, 3.26 -19.456)
In [7]:
length = line.length #lenght of line
centroid = line.centroid #center of line
print(f"Length of our line: {length:.2f} units")
print(f"Centroid: {centroid}")
Length of our line: 28.88 units
Centroid: POINT (4.909750627138961 -9.134289216228249)

Polygons¶

So the same logic. Polygons essentially mean area. An area would have lines surrounded. So it uses points to create that shape.

In [8]:
from shapely.geometry import Polygon

pol = Polygon([point1, point2, point3])
pol
Out[8]:
In [9]:
#Polygon WKT representation has double parentheses around the coordinates

print(pol)
POLYGON ((3.1 4.9, 6.7 -20.2, 3.26 -19.456, 3.1 4.9))

MultiPoint, MultiLineString and MultiPolygon¶

In [10]:
from shapely.geometry import MultiPoint, MultiLineString, MultiPolygon

multipoint = MultiPoint([Point(2, 2), Point(3, 3)])
multipoint
Out[10]:
In [11]:
multiline = MultiLineString([LineString([(2, 4), (7, 3)]),
                             LineString([(6, 3), (6, 1)])])
multiline
Out[11]:
In [12]:
multipoly = MultiPolygon([Polygon([(0, 0), (0, 4), (4, 4)]),
                          Polygon([(6, 6), (6, 12), (12, 12)])])
multipoly
Out[12]:

So why do we learn these?

Well, these will become our houses(points), roads(lines) and our countries(polygons)

Pandas and Geopandas¶

In [13]:
import pandas as pd

d= {'var1':[1, 2,3,4,5],
    "var2": [6,7,8,9,10]}
df = pd.DataFrame(d)

df
Out[13]:
var1 var2
0 1 6
1 2 7
2 3 8
3 4 9
4 5 10
In [14]:
type(df)
Out[14]:
pandas.core.frame.DataFrame
In [15]:
type(df['var1'])
Out[15]:
pandas.core.series.Series
In [16]:
ucdp=pd.read_csv("ged211.csv")
C:\Users\onery\AppData\Local\Temp\ipykernel_16232\1919793444.py:1: DtypeWarning: Columns (47) have mixed types. Specify dtype option on import or set low_memory=False.
  ucdp=pd.read_csv("ged211.csv")
In [17]:
ucdp.columns
Out[17]:
Index(['id', 'relid', 'year', 'active_year', 'code_status', 'type_of_violence',
       'conflict_dset_id', 'conflict_new_id', 'conflict_name', 'dyad_dset_id',
       'dyad_new_id', 'dyad_name', 'side_a_dset_id', 'side_a_new_id', 'side_a',
       'side_b_dset_id', 'side_b_new_id', 'side_b', 'number_of_sources',
       'source_article', 'source_office', 'source_date', 'source_headline',
       'source_original', 'where_prec', 'where_coordinates',
       'where_description', 'adm_1', 'adm_2', 'latitude', 'longitude',
       'geom_wkt', 'priogrid_gid', 'country', 'country_id', 'region',
       'event_clarity', 'date_prec', 'date_start', 'date_end', 'deaths_a',
       'deaths_b', 'deaths_civilians', 'deaths_unknown', 'best', 'high', 'low',
       'gwnoa', 'gwnob'],
      dtype='object')
In [18]:
#knowing latitude and longitude enough to create geo dataframe
ucdp[['year', 'country', 'latitude', 'longitude', 'geom_wkt']]
Out[18]:
year country latitude longitude geom_wkt
0 2017 Afghanistan 34.531094 69.162796 POINT (69.162796 34.531094)
1 1989 Afghanistan 34.333330 70.416670 POINT (70.41667 34.33333)
2 1989 Afghanistan 36.750000 68.750000 POINT (68.75 36.75)
3 1989 Afghanistan 35.315833 69.038889 POINT (69.038889 35.315833)
4 1989 Afghanistan 34.531094 69.162796 POINT (69.162796 34.531094)
... ... ... ... ... ...
261859 1989 Zimbabwe (Rhodesia) -20.500000 32.500000 POINT (32.5 -20.5)
261860 1989 Zimbabwe (Rhodesia) -19.000000 32.500000 POINT (32.5 -19)
261861 1990 Zimbabwe (Rhodesia) -18.000000 32.833333 POINT (32.833333 -18)
261862 1990 Zimbabwe (Rhodesia) -19.000000 32.500000 POINT (32.5 -19)
261863 1990 Zimbabwe (Rhodesia) -16.783333 31.583333 POINT (31.583333 -16.783333)

261864 rows × 5 columns

In [19]:
#import geopandas
import geopandas as gpd
In [20]:
#shape file
path= "G:\My Drive\shapefiles\world\World_Countries__Generalized_.shp"

world= gpd.read_file(path)
In [21]:
world.plot()
Out[21]:
<Axes: >
In [22]:
fp = gpd.datasets.get_path("naturalearth_lowres")

admin = gpd.read_file(fp)

admin.plot()
C:\Users\onery\AppData\Local\Temp\ipykernel_16232\4213141844.py:1: FutureWarning: The geopandas.dataset module is deprecated and will be removed in GeoPandas 1.0. You can get the original 'naturalearth_lowres' data from https://www.naturalearthdata.com/downloads/110m-cultural-vectors/.
  fp = gpd.datasets.get_path("naturalearth_lowres")
Out[22]:
<Axes: >
In [23]:
#UCDP dataset turn into geodataframe
#first way
#notice wkt, crs, 4326

gs = gpd.GeoSeries.from_wkt(ucdp['geom_wkt'])
geo_event = gpd.GeoDataFrame(ucdp, geometry=gs, crs="EPSG:4326")
In [24]:
#second way
#notice xy cordinates
# as long as we have cordinates we can visualize.
ucdp["geometry"] = gpd.points_from_xy(x=ucdp["longitude"],
                                      y=ucdp["latitude"],
                                      crs="EPSG:4326")

ucdp = gpd.GeoDataFrame(ucdp)
In [25]:
ucdp.crs
Out[25]:
<Geographic 2D CRS: EPSG:4326>
Name: WGS 84
Axis Info [ellipsoidal]:
- Lat[north]: Geodetic latitude (degree)
- Lon[east]: Geodetic longitude (degree)
Area of Use:
- name: World.
- bounds: (-180.0, -90.0, 180.0, 90.0)
Datum: World Geodetic System 1984 ensemble
- Ellipsoid: WGS 84
- Prime Meridian: Greenwich

The EPSG code is 4326 which refers to the WGS84 coordinate system. In the geospatial world as it is perhaps the most commonly used coordinate reference system in the world.

In [26]:
#the same geo features

ucdp[['year', 'country', 'latitude', 'longitude', 'geom_wkt', "geometry"]]
Out[26]:
year country latitude longitude geom_wkt geometry
0 2017 Afghanistan 34.531094 69.162796 POINT (69.162796 34.531094) POINT (69.16280 34.53109)
1 1989 Afghanistan 34.333330 70.416670 POINT (70.41667 34.33333) POINT (70.41667 34.33333)
2 1989 Afghanistan 36.750000 68.750000 POINT (68.75 36.75) POINT (68.75000 36.75000)
3 1989 Afghanistan 35.315833 69.038889 POINT (69.038889 35.315833) POINT (69.03889 35.31583)
4 1989 Afghanistan 34.531094 69.162796 POINT (69.162796 34.531094) POINT (69.16280 34.53109)
... ... ... ... ... ... ...
261859 1989 Zimbabwe (Rhodesia) -20.500000 32.500000 POINT (32.5 -20.5) POINT (32.50000 -20.50000)
261860 1989 Zimbabwe (Rhodesia) -19.000000 32.500000 POINT (32.5 -19) POINT (32.50000 -19.00000)
261861 1990 Zimbabwe (Rhodesia) -18.000000 32.833333 POINT (32.833333 -18) POINT (32.83333 -18.00000)
261862 1990 Zimbabwe (Rhodesia) -19.000000 32.500000 POINT (32.5 -19) POINT (32.50000 -19.00000)
261863 1990 Zimbabwe (Rhodesia) -16.783333 31.583333 POINT (31.583333 -16.783333) POINT (31.58333 -16.78333)

261864 rows × 6 columns

In [27]:
geo_event.plot(color='r', markersize=5)
Out[27]:
<Axes: >
In [28]:
import matplotlib.pyplot as plt

fig, ax= plt.subplots(figsize=(15, 10))

world.plot(ax=ax, alpha=0.2, color='gray', edgecolor='k')
geo_event.plot(ax=ax, c='r', alpha=0.6, edgecolor='k',markersize=9)

ax.set_title('Conflict Event Database, UCDP', pad=35,fontdict={'fontsize':20})
plt.axis('off')
fig.tight_layout()

plt.show()

Geocoding¶

Let's say you have some addresses and you want to geocode them. There are ways you can do in geopandas.

In [29]:
# Sample data with addresses (replace these with your own addresses)
data = {
    'Name': ['Place A', 'Place B', 'Place C', 'Place D', 'Place E'],
    'Address': [
        '1600 Amphitheatre Parkway, Mountain View, CA',
        '1 Infinite Loop, Cupertino, CA',
        '350 5th Ave, New York, NY',
        '221B Baker St, London, UK',
        'Eiffel Tower, Paris, France']
    }
In [30]:
df= pd.DataFrame(data)

df
Out[30]:
Name Address
0 Place A 1600 Amphitheatre Parkway, Mountain View, CA
1 Place B 1 Infinite Loop, Cupertino, CA
2 Place C 350 5th Ave, New York, NY
3 Place D 221B Baker St, London, UK
4 Place E Eiffel Tower, Paris, France
In [31]:
# Import the geocoding tool
from geopandas.tools import geocode

# Geocode addresses using Nominatim.
# You can provide your own
geo = geocode(data["Address"],
              provider="nominatim",
              user_agent="pythongis",
              timeout=10)
In [32]:
geo
Out[32]:
geometry address
0 POINT (-122.08461 37.42176) Google Headquarters, 1600, Amphitheatre Parkwa...
1 POINT (-122.03042 37.33140) Apple Infinite Loop, 1, Infinite Loop, Apple C...
2 POINT (-73.98566 40.74844) Empire State Building, 350, 5th Avenue, Manhat...
3 POINT (-0.15824 51.52339) 221B Baker Street, Baker Street, Marylebone, L...
4 POINT (2.29450 48.85826) Tour Eiffel, 5, Avenue Anatole France, Quartie...
In [33]:
import matplotlib.pyplot as plt

fig, ax= plt.subplots(figsize=(15, 10))
world.plot(ax=ax, alpha=0.2, color='gray', edgecolor='k')
geo.plot(ax=ax, c='r')

plt.show()
In [34]:
pip install geodatasets
Collecting geodatasets
  Downloading geodatasets-2023.3.0-py3-none-any.whl (17 kB)
Requirement already satisfied: pooch in c:\users\onery\anaconda3\lib\site-packages (from geodatasets) (1.4.0)
Requirement already satisfied: requests in c:\users\onery\anaconda3\lib\site-packages (from pooch->geodatasets) (2.28.1)
Requirement already satisfied: appdirs in c:\users\onery\anaconda3\lib\site-packages (from pooch->geodatasets) (1.4.4)
Requirement already satisfied: packaging in c:\users\onery\anaconda3\lib\site-packages (from pooch->geodatasets) (22.0)
Requirement already satisfied: idna<4,>=2.5 in c:\users\onery\anaconda3\lib\site-packages (from requests->pooch->geodatasets) (3.4)
Requirement already satisfied: charset-normalizer<3,>=2 in c:\users\onery\anaconda3\lib\site-packages (from requests->pooch->geodatasets) (2.0.4)
Requirement already satisfied: certifi>=2017.4.17 in c:\users\onery\anaconda3\lib\site-packages (from requests->pooch->geodatasets) (2023.5.7)
Requirement already satisfied: urllib3<1.27,>=1.21.1 in c:\users\onery\anaconda3\lib\site-packages (from requests->pooch->geodatasets) (1.26.14)
Installing collected packages: geodatasets
Successfully installed geodatasets-2023.3.0
Note: you may need to restart the kernel to use updated packages.
In [35]:
import geopandas as gpd
import geodatasets as gds

chicago = gpd.read_file(gds.get_path("geoda.chicago_commpop"))

groceries = gpd.read_file(gds.get_path("geoda.groceries"))
C:\Users\onery\anaconda3\lib\site-packages\paramiko\transport.py:219: CryptographyDeprecationWarning: Blowfish has been deprecated
  "class": algorithms.Blowfish,
Downloading file 'chicago_commpop.zip' from 'https://geodacenter.github.io/data-and-lab//data/chicago_commpop.zip' to 'C:\Users\onery\AppData\Local\geodatasets\geodatasets\Cache'.
Extracting 'chicago_commpop/chicago_commpop.geojson' from 'C:\Users\onery\AppData\Local\geodatasets\geodatasets\Cache\chicago_commpop.zip' to 'C:\Users\onery\AppData\Local\geodatasets\geodatasets\Cache\chicago_commpop.zip.unzip'
Downloading file 'grocery.zip' from 'https://geodacenter.github.io/data-and-lab//data/grocery.zip' to 'C:\Users\onery\AppData\Local\geodatasets\geodatasets\Cache'.
Extracting 'grocery/chicago_sup.shp' from 'C:\Users\onery\AppData\Local\geodatasets\geodatasets\Cache\grocery.zip' to 'C:\Users\onery\AppData\Local\geodatasets\geodatasets\Cache\grocery.zip.unzip'
Extracting 'grocery/chicago_sup.dbf' from 'C:\Users\onery\AppData\Local\geodatasets\geodatasets\Cache\grocery.zip' to 'C:\Users\onery\AppData\Local\geodatasets\geodatasets\Cache\grocery.zip.unzip'
Extracting 'grocery/chicago_sup.shx' from 'C:\Users\onery\AppData\Local\geodatasets\geodatasets\Cache\grocery.zip' to 'C:\Users\onery\AppData\Local\geodatasets\geodatasets\Cache\grocery.zip.unzip'
Extracting 'grocery/chicago_sup.prj' from 'C:\Users\onery\AppData\Local\geodatasets\geodatasets\Cache\grocery.zip' to 'C:\Users\onery\AppData\Local\geodatasets\geodatasets\Cache\grocery.zip.unzip'
In [36]:
chicago.plot()
Out[36]:
<Axes: >
In [37]:
groceries.plot()
Out[37]:
<Axes: >
In [38]:
fig, ax = plt.subplots()

chicago.plot(ax=ax, color='white', edgecolor='black')

groceries.plot(ax=ax, marker='o', color='red', markersize=5)

plt.show()
In [39]:
chicago.crs
Out[39]:
<Geographic 2D CRS: EPSG:4326>
Name: WGS 84
Axis Info [ellipsoidal]:
- Lat[north]: Geodetic latitude (degree)
- Lon[east]: Geodetic longitude (degree)
Area of Use:
- name: World.
- bounds: (-180.0, -90.0, 180.0, 90.0)
Datum: World Geodetic System 1984 ensemble
- Ellipsoid: WGS 84
- Prime Meridian: Greenwich
In [40]:
groceries.crs
Out[40]:
<Projected CRS: PROJCS["Transverse_Mercator",GEOGCS["GCS_GRS 1980( ...>
Name: Transverse_Mercator
Axis Info [cartesian]:
- [east]: Easting (US survey foot)
- [north]: Northing (US survey foot)
Area of Use:
- undefined
Coordinate Operation:
- name: unnamed
- method: Transverse Mercator
Datum: D_unknown
- Ellipsoid: GRS80
- Prime Meridian: Greenwich
In [41]:
# so it looks like they are not using the same crs.
#lets convert one's crs to other
groceries = groceries.to_crs(chicago.crs)
In [42]:
fig, ax = plt.subplots()

chicago.plot(ax=ax, color='white', edgecolor='black')
chicago.plot(ax=ax, column="POP2010", legend=True, cmap='viridis_r')
groceries.plot(ax=ax, marker='o', color='k', markersize=4, edgecolor='red')


ax.set_title('Chicago Population and Groceries', pad=35,fontdict={'fontsize':12})

plt.axis('off')
fig.tight_layout()

plt.show()

Plotly for GIS¶

Check out the library here

In [43]:
import plotly.express as px

df = px.data.election()
geojson = px.data.election_geojson()

print(df["district"][2])
print(geojson["features"][0]["properties"])
11-Sault-au-Récollet
{'district': '11-Sault-au-Récollet'}
In [44]:
# from plotly website

import plotly.express as px

df = px.data.election()
geojson = px.data.election_geojson()

fig = px.choropleth_mapbox(df, geojson=geojson, color="Bergeron",
                           locations="district", featureidkey="properties.district",
                           center={"lat": 45.5517, "lon": -73.7073},
                           mapbox_style="carto-positron", zoom=9)
fig.update_layout(margin={"r":0,"t":0,"l":0,"b":0})
fig.show()
In [45]:
# from plotly website

import plotly.graph_objects as go

import pandas as pd

df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/2014_us_cities.csv')
df.head()

df['text'] = df['name'] + '<br>Population ' + (df['pop']/1e6).astype(str)+' million'
limits = [(0,2),(3,10),(11,20),(21,50),(50,3000)]
colors = ["royalblue","crimson","lightseagreen","orange","lightgrey"]
cities = []
scale = 5000

fig = go.Figure()

for i in range(len(limits)):
    lim = limits[i]
    df_sub = df[lim[0]:lim[1]]
    fig.add_trace(go.Scattergeo(
        locationmode = 'USA-states',
        lon = df_sub['lon'],
        lat = df_sub['lat'],
        text = df_sub['text'],
        marker = dict(
            size = df_sub['pop']/scale,
            color = colors[i],
            line_color='rgb(40,40,40)',
            line_width=0.5,
            sizemode = 'area'
        ),
        name = '{0} - {1}'.format(lim[0],lim[1])))

fig.update_layout(
        title_text = '2014 US city populations<br>(Click legend to toggle traces)',
        showlegend = True,
        geo = dict(
            scope = 'usa',
            landcolor = 'rgb(217, 217, 217)',
        )
    )

fig.show()

OSMnx¶

OSMnx is pronounced as the initialism: “oh-ess-em-en-ex”. It is built on top of NetworkX and GeoPandas, and interacts with OpenStreetMap APIs.

In [46]:
pip install osmnx
Collecting osmnx
  Downloading osmnx-1.6.0-py3-none-any.whl (101 kB)
     -------------------------------------- 101.4/101.4 kB 2.9 MB/s eta 0:00:00
Requirement already satisfied: numpy>=1.20 in c:\users\onery\anaconda3\lib\site-packages (from osmnx) (1.23.5)
Requirement already satisfied: shapely>=2.0 in c:\users\onery\anaconda3\lib\site-packages (from osmnx) (2.0.1)
Requirement already satisfied: pandas>=1.1 in c:\users\onery\anaconda3\lib\site-packages (from osmnx) (1.5.3)
Requirement already satisfied: geopandas>=0.12 in c:\users\onery\anaconda3\lib\site-packages (from osmnx) (0.13.2)
Requirement already satisfied: requests>=2.27 in c:\users\onery\anaconda3\lib\site-packages (from osmnx) (2.28.1)
Requirement already satisfied: networkx>=2.5 in c:\users\onery\anaconda3\lib\site-packages (from osmnx) (2.8.4)
Requirement already satisfied: fiona>=1.8.19 in c:\users\onery\anaconda3\lib\site-packages (from geopandas>=0.12->osmnx) (1.9.4.post1)
Requirement already satisfied: packaging in c:\users\onery\anaconda3\lib\site-packages (from geopandas>=0.12->osmnx) (22.0)
Requirement already satisfied: pyproj>=3.0.1 in c:\users\onery\anaconda3\lib\site-packages (from geopandas>=0.12->osmnx) (3.6.0)
Requirement already satisfied: pytz>=2020.1 in c:\users\onery\anaconda3\lib\site-packages (from pandas>=1.1->osmnx) (2022.7)
Requirement already satisfied: python-dateutil>=2.8.1 in c:\users\onery\anaconda3\lib\site-packages (from pandas>=1.1->osmnx) (2.8.2)
Requirement already satisfied: certifi>=2017.4.17 in c:\users\onery\anaconda3\lib\site-packages (from requests>=2.27->osmnx) (2023.5.7)
Requirement already satisfied: charset-normalizer<3,>=2 in c:\users\onery\anaconda3\lib\site-packages (from requests>=2.27->osmnx) (2.0.4)
Requirement already satisfied: urllib3<1.27,>=1.21.1 in c:\users\onery\anaconda3\lib\site-packages (from requests>=2.27->osmnx) (1.26.14)
Requirement already satisfied: idna<4,>=2.5 in c:\users\onery\anaconda3\lib\site-packages (from requests>=2.27->osmnx) (3.4)
Requirement already satisfied: click~=8.0 in c:\users\onery\anaconda3\lib\site-packages (from fiona>=1.8.19->geopandas>=0.12->osmnx) (8.0.4)
Requirement already satisfied: cligj>=0.5 in c:\users\onery\anaconda3\lib\site-packages (from fiona>=1.8.19->geopandas>=0.12->osmnx) (0.7.2)
Requirement already satisfied: six in c:\users\onery\anaconda3\lib\site-packages (from fiona>=1.8.19->geopandas>=0.12->osmnx) (1.16.0)
Requirement already satisfied: click-plugins>=1.0 in c:\users\onery\anaconda3\lib\site-packages (from fiona>=1.8.19->geopandas>=0.12->osmnx) (1.1.1)
Requirement already satisfied: attrs>=19.2.0 in c:\users\onery\anaconda3\lib\site-packages (from fiona>=1.8.19->geopandas>=0.12->osmnx) (22.1.0)
Requirement already satisfied: colorama in c:\users\onery\anaconda3\lib\site-packages (from click~=8.0->fiona>=1.8.19->geopandas>=0.12->osmnx) (0.4.6)
Installing collected packages: osmnx
Successfully installed osmnx-1.6.0
Note: you may need to restart the kernel to use updated packages.
In [47]:
# Here is binghamton

import osmnx as ox
import matplotlib.pyplot as plt


place_name = ["Binghamton, NY", "Vestal, NY"]

# OSM street network from the location
graph = ox.graph_from_place(place_name)
fig, ax = ox.plot_graph(graph, bgcolor='k',
                        node_color='w', node_edgecolor='g',
                        node_size=10, node_alpha=0.8, edge_linewidth=0.2)
In [48]:
bingo = ox.geocode_to_gdf(place_name)

bingo.plot()
Out[48]:
<Axes: >
In [49]:
 # buildings


buildings = ox.geometries_from_place(place_name,
                                     tags={'building':True})
C:\Users\onery\AppData\Local\Temp\ipykernel_16232\1441714557.py:4: UserWarning:

The `geometries` module and `geometries_from_X` functions have been renamed the `features` module and `features_from_X` functions. Use these instead. The `geometries` module and function names are deprecated and will be removed in a future release.

In [50]:
buildings.head(3)
Out[50]:
addr:state building ele gnis:county_name gnis:feature_id gnis:import_uuid gnis:reviewed name source geometry ... payment:visa payment:wic baseball bin healthcare:speciality air_conditioning telecom ways type multipolygon
element_type osmid
node 368044250 NY yes 334 Broome 2367881 57871b70-0100-4405-bb30-88b2e001a944 no Goudey Steam Station USGS Geonames POINT (-75.97417 42.10389) ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
368044437 NY yes 262 Broome 2376541 57871b70-0100-4405-bb30-88b2e001a944 no Binghamton Boys Club USGS Geonames POINT (-75.91252 42.10258) ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
368044444 NY yes 273 Broome 2376604 57871b70-0100-4405-bb30-88b2e001a944 no Susquehanna Valley Home USGS Geonames POINT (-75.88722 42.10028) ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN

3 rows × 129 columns

In [51]:
#restaurants
restaurants = ox.geometries_from_place(place_name,
                                  tags={"amenity": "restaurant"})

restaurants.head()
C:\Users\onery\AppData\Local\Temp\ipykernel_16232\103359837.py:2: UserWarning:

The `geometries` module and `geometries_from_X` functions have been renamed the `features` module and `features_from_X` functions. Use these instead. The `geometries` module and function names are deprecated and will be removed in a future release.

Out[51]:
amenity name opening_hours payment:cash payment:visa wheelchair wheelchair:description geometry addr:city addr:housenumber ... addr:flats nodes building area official_name leisure nysgissam:review note building:levels building:part
element_type osmid
node 2447270561 restaurant Burger Mondays Mo-Sa 11:30-24:00 yes yes no step at front door POINT (-75.91174 42.10072) NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
2622916939 restaurant California Grill NaN NaN NaN NaN NaN POINT (-76.03779 42.08995) Vestal 912 ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
2622921967 restaurant Olive Garden 11:00-22:00 NaN NaN NaN NaN POINT (-76.03169 42.09121) Vestal 1112 ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
2622922572 restaurant Red Lobster 11:00-22:00 NaN NaN NaN NaN POINT (-76.02984 42.09145) Vestal 1200 ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
2622952585 restaurant Lemongrass Kitchen Su-Th 16:30-21:00; Fr-Sa 16:30-22:30; Mo off NaN NaN NaN NaN POINT (-76.02728 42.09197) Vestal 1550 ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN

5 rows × 43 columns

In [52]:
# nodes and edges
nodes, edges = ox.graph_to_gdfs(graph)
In [53]:
fig, ax = plt.subplots(figsize=(12,8))

# Plot the footprint
bingo.plot(ax=ax, facecolor='black')

# Plot street edges
edges.plot(ax=ax, linewidth=1, edgecolor='#BC8F8F')
Out[53]:
<Axes: >
In [54]:
fig, ax = plt.subplots(figsize=(12,8))

# Plot the footprint
bingo.plot(ax=ax, facecolor='black')

# Plot street edges
edges.plot(ax=ax, linewidth=1, edgecolor='#BC8F8F')

# Plot buildings
buildings.plot(ax=ax, facecolor='khaki', alpha=0.7)

# Plot restaurants
restaurants.plot(ax=ax, color='green', alpha=0.7, markersize=10)

plt.axis('off')
fig.tight_layout()